<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-card class="box-card">
      <!-- 添加角色区域 -->
      <el-button type='primary' @click='addRoleDialog'>添加角色</el-button>
      <!-- 角色列表 -->
      <el-table border stripe :data="rolesList" style="width: 100%">
        <!-- 展开行的操作 -->
        <el-table-column type="expand" width="50">
          <template slot-scope='scope'>
            <el-row :class="['bdBottom', 'vCenter', i1 === 0 ? 'bdTop' : '']" :key='role.id'
              v-for='(role, i1) in scope.row.children'>
              <!-- 渲染一级权限 -->
              <el-col :span="8">
                <el-tag @close='deleteRightById(scope.row,role.id)' closable>{{ role.authName }}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 渲染二级和三级权限 -->
              <el-col :span='16'>
                <el-row :class="['vCenter', i2 === 0 ? '' : 'bdTop']" v-for='(rightRole1,i2) in role.children'
                  :key="rightRole1.id">
                  <el-col :span='6'>
                    <el-tag @close='deleteRightById(scope.row,rightRole1.id)' type='success' closable>
                      {{ rightRole1.authName }}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <el-col :span='18'>
                    <el-tag @close='deleteRightById(scope.row,rightRole2.id)' v-for='rightRole2 in rightRole1.children'
                      :key="rightRole2.id" type='warning' closable>
                      {{ rightRole2.authName }}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <!-- 索引列 -->
        <el-table-column type="index" label='#' width="50">
        </el-table-column>
        <el-table-column prop="roleName" label="角色名称" width="300">
        </el-table-column>
        <el-table-column prop="roleDesc" label="角色描述" width="300">
        </el-table-column>
        <el-table-column label="操作" width="300">
          <template slot-scope='scope'>
            <div>
              <el-button size='mini' type="primary" icon="el-icon-edit">编辑</el-button>
              <el-button size='mini' type="danger" icon="el-icon-delete">删除</el-button>
              <el-button size='mini' type="warning" icon="el-icon-setting" @click='showRightDialog(scope.row)'>分配权限
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 添加用户的对话框 -->
      <el-dialog @close='addRoleFormClosed' title="添加角色" :visible.sync="addRoleDialogVisible" width="50%">
        <el-form ref="addRolesFormRef" :model="addRolesForm" label-width="80px">
          <el-form-item label="角色名称" prop="roleName">
            <el-input v-model="addRolesForm.roleName"></el-input>
          </el-form-item>
          <el-form-item label="角色描述" prop="roleDesc">
            <el-input v-model="addRolesForm.roleDesc"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="addRoleDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addRole">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 分配权限的对话框 -->
      <el-dialog @close='allotRightDialogClosed' title="分配权限" :visible.sync="showRightDialogVisible" width="50%">
        <!-- 所有的权限树形列表 -->
        <!-- default-expand-all:默认打开所有的子节点 -->
        <!-- show-checkbox 显示节点可被选择 -->
        <!-- default-checked-keys 默认的已经选中的key值数组 -->
        <el-tree ref='treeRef' :default-checked-keys='defKeys' node-key='id' show-checkbox default-expand-all
          :data="rightsList" :props="treeDefProps"></el-tree>
        <span slot="footer" class="dialog-footer">
          <el-button @click="showRightDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="allotRight">确 定</el-button>
        </span>
      </el-dialog>
    </el-card>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        // 所有的角色列表数据
        rolesList: [],
        // 控制添加用户对话框的显示和隐藏
        addRoleDialogVisible: false,
        // 添加角色的数据
        addRolesForm: {
          roleName: '',
          roleDesc: ''
        },
        // 分配权限对话框的显示与隐藏
        showRightDialogVisible: false,
        // 保存所有权限的数据信息
        rightsList: [],
        // 树形权限表的匹配信息对象
        treeDefProps: {
          label: 'authName',
          children: 'children'
        },
        // 角色已经拥有的默认的key值数组
        defKeys: [],
        // 保存当前角色的id值
        roleId: ''
      }
    },
    created() {
      this.getAllRolesList()
    },
    methods: {
      // 获取所有的角色列表数据
      async getAllRolesList() {
        const {
          data: res
        } = await this.$http.get('roles')
        // console.log(res)
        if (res.meta.status !== 200) {
          return this.$message.error('获取角色数据列表失败')
        }
        this.rolesList = res.data
      },
      // 添加角色
      addRoleDialog() {
        this.addRoleDialogVisible = true
        // 弹出添加角色对话框
      },
      // 关闭添加角色对话框的事件
      addRoleFormClosed() {
        this.$refs.addRolesFormRef.resetFields()
      },
      // 添加角色
      async addRole() {
        // 发送网络请求添加角色
        const {
          data: res
        } = await this.$http.post('roles', this.addRolesForm)
        // console.log(res)
        if (res.meta.status !== 201) {
          return this.$message.error('添加角色失败，请重试')
        }
        // 添加角色成功的提示
        this.$message.success('添加角色成功')
        // 刷新角色列表
        this.getAllRolesList()
        // 隐藏对话框
        this.addRoleDialogVisible = false
      },
      // 根据id删除对应的权限
      async deleteRightById(role, rightId) {
        // 弹窗提示是否删除
        const confirmResult = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)
        // console.log(confirmResult)
        if (confirmResult !== 'confirm') {
          return this.$message.info('取消了删除')
        }
        // 发起网络请求删除权限
        const {
          data: res
        } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
        if (res.meta.status !== 200) return this.$message.error('删除失败')
        // 刷新角色列表 不可取
        // this.getAllRolesList()
        // 为当前的角色重新赋值
        role.children = res.data
        // 提示删除权限成功
        this.$message.success('删除该权限成功')
      },
      // 点击分配权限按钮，弹出对话框
      async showRightDialog(role) {
        // 保存当前角色id到data中
        this.roleId = role.id
        // console.log(this.roleId)
        // 发送网络请求获取所有权限数据
        const {
          data: res
        } = await this.$http.get('rights/tree')
        // console.log(res)
        if (res.meta.status !== 200) return this.$mesage.error('获取所有权限列表数据失败')
        // 保存所有权限数据 到data中
        this.rightsList = res.data
        // console.log(this.rightsList)
        // 获取所有的选中的和半选的id
        // 使用递归获得所有三级权限的id,拿到当前角色下的所有三级权限的id
        this.getLeafKeys(role, this.defKeys)
        // 获取成功提示
        this.$message.success('获取所有权限数据成功')
        // 显示分配权限的对话框
        this.showRightDialogVisible = true
      },
      // 获取节点中的所有id，保存到数组中
      getLeafKeys(node, arr) {
        if (!node.children) {
          return arr.push(node.id)
        }
        node.children.forEach(item => {
          // 递归调用
          this.getLeafKeys(item, arr)
        })
      },
      // 分配权限对话框消失的关闭事件
      allotRightDialogClosed() {
        // defKeys清空
        this.defKeys = []
      },
      // 点击确定分配权限
      async allotRight() {
        // 获取到所有选中和半选中的节点组成新数组
        const keysArr = [
          ...this.$refs.treeRef.getHalfCheckedKeys(),
          ...this.$refs.treeRef.getCheckedKeys()
        ]
        // console.log(keysArr)
        // 发起网络请求分配权限
        // 数组以 , 拆分，输出为字符串
        const idStr = keysArr.join(',')
        // console.log(idStr)
        const {
          data: res
        } = await this.$http.post(`roles/${this.roleId}/rights`, {
          rids: idStr
        })
        if (res.meta.status !== 200) return this.$message.error('权限分配失败')
        this.$message.success('权限分配成功')
        // 刷新角色列表
        this.getAllRolesList()
        // 隐藏对话框
        this.showRightDialogVisible = false
      }
    }
  }

</script>
<style lang="less" scoped>
  .el-button {
    margin-bottom: 15px;

  }

  .el-card {
    margin-top: 15px;
  }

  .el-tag {
    margin: 10px;
  }

  .el-row {
    border: 1px solid #eee;
  }

  .bdTop {
    border-top: 1px solid #eee;
  }

  .bdBottom {
    border-bottom: 1px solid #eee;
  }

  .vCenter {
    display: flex;
    align-items: center;
  }

</style>
